package com.ylyq.lingoserver.lingo;

import com.lindo.Lingd18;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class LingoInvoker {
    private static Logger logger = LoggerFactory.getLogger(LingoInvoker.class);

    private Object m_pnLngEnv;
    private int m_nLastIterationCount;
    private Lingd18 lng;
    private int nErrorCode;
    private String errorMessage;

    static {
        try {
            System.loadLibrary("Lingj64_18");
        } catch (Exception e) {
            logger.error("ctc LingoInvoker Load Exception: " + e.toString());
            e.printStackTrace();
        }
    }

    private static int solverCallback(Object pnLng, int iLoc, Object jobjMyObj) {
        LingoInvoker rt = (LingoInvoker) jobjMyObj;
        int nIterations[] = new int[1];
        rt.lng.LSgetCallbackInfoIntLng(pnLng, Lingd18.LS_IINFO_ITERATIONS_LNG, nIterations);

        if (nIterations[0] >= rt.m_nLastIterationCount) {
            rt.m_nLastIterationCount = nIterations[0];
        }
        return 0;
    }

    private static int solverErrorCallback(Object pnLng, int nErrCode, String jsErrMessage, Object jobjMyObj) {
        LingoInvoker rt = (LingoInvoker) jobjMyObj;
        rt.setErrorCode(nErrCode);
        rt.setErrorMessage(jsErrMessage);
        return 0;
    }

    public boolean solve(String lingoModelPath) {

        logger.info("***lingo ={} 模型开始执行***", lingoModelPath);
        this.lng = new Lingd18();
        int nError = lng.LSERR_NO_ERROR_LNG;

        m_pnLngEnv = lng.LScreateEnvLng();
        if (m_pnLngEnv == null) {
            logger.error("***ctc LingoInvoker Unable to create Lingo environment***");
            return false;
        }

        nError = lng.LSsetCallbackSolverLng(m_pnLngEnv, "solverCallback", this);
        if (nError != lng.LSERR_NO_ERROR_LNG) {
            logger.error("***ctc LingoInvoker LSsetCallbackSolverLng error***: " + nError);
            return false;
        }

        // ...and the error callback function
        nError = lng.LSsetCallbackErrorLng(m_pnLngEnv, "solverErrorCallback", this);
        if (nErrorCode != lng.LSERR_NO_ERROR_LNG) {
            logger.error("***ctc LingoInvoker LSsetCallbackErrorLng error***: " + nError);
            return false;
        }

        // echo input to log file
        String sScript = "SET ECHOIN 0" + "\n";
        sScript = sScript + "SET TERSEO 1" + "\n";
        sScript = sScript + "TAKE " + lingoModelPath + "\n";
        sScript = sScript + "GO" + "\n";
        sScript = sScript + "QUIT" + "\n";

        // run the script
        nError = lng.LSexecuteScriptLng(m_pnLngEnv, sScript);
        if (nError != lng.LSERR_NO_ERROR_LNG) {
            logger.error("***ctc LingoInvoker LSexecuteScriptLng error***: " + nError);
            return false;
        }


        // delete the Lingo environment
        lng.LSdeleteEnvLng(m_pnLngEnv);
        logger.info("***lingo 模型执行结束 = {}***", lingoModelPath);
        return true;
    }

    public void setErrorCode(int nError) {
        nErrorCode = nError;
    }

    public int getErrorCode() {
        return nErrorCode;
    }

    public String getErrorMessage() {
        return errorMessage;
    }

    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }

    public static void main(String args[]) {
        LingoInvoker invoker = new LingoInvoker();
        if (invoker.solve("D:\\file\\lingo\\lingosh.lng") && invoker.getErrorCode() == 0) {
            logger.error("***DONE***");
        } else {
            logger.error("未结束呢");
        }

    }

}
